package br.ufpe.cin.wormbox.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.util.HashMap;

public class Servidor {

	private File arquivosUsuarios = new File("wormbox/userfiles");
	private File arquivosConf = new File("wormbox/server/cfg");
	private File folderTemp = new File("wormbox/server/tmp");
	public HashMap<String, DadosUsuario> conjuntoUsers;
	
	public Servidor() {
		this.initFolders();
		this.initLoginData();
	}
	
	public void initFolders() {
		if(!this.arquivosConf.exists()) {
			this.arquivosConf.mkdirs();
		}
		
		if(!this.arquivosUsuarios.exists()) {
			this.arquivosUsuarios.mkdirs();
		}
		
		if(!this.folderTemp.exists()) {
			this.folderTemp.mkdirs();
		}
	}
	
	@SuppressWarnings("unchecked")
	public void initLoginData() {
		File f = new File(this.arquivosConf, "ld.wbd");
		
		if(f.exists()) {
			try {
				FileInputStream fis = new FileInputStream(f);
				ObjectInputStream ois = new ObjectInputStream(fis);
				
				Object o = ois.readObject();
				
				ois.close();
				fis.close();
				if(o instanceof HashMap<?, ?>) {
					this.conjuntoUsers = (HashMap<String, DadosUsuario>) o;
				} else {
					throw new RuntimeException("Deu merda no arquivo de senhas");
				}
			} catch (FileNotFoundException e) {
			} catch (IOException e) {
			} catch (ClassNotFoundException e) {
			}
		} else {
			this.conjuntoUsers = new HashMap<String, DadosUsuario>();
		}
	}
	
	public void salvarConfig() {
		File f = new File(this.arquivosConf, "ld.wbd");
		
		try {
			if(f.exists()) {
				f.createNewFile();
			}
			
			FileOutputStream fos = new FileOutputStream(f);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			
			oos.writeObject(this.conjuntoUsers);
			
			oos.close();
			fos.close();
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
	}
	
	public boolean inserirUsuario(String login, DadosUsuario data) {
		if(!conjuntoUsers.containsKey(login)) {
			conjuntoUsers.put(login, data);
			
			(new File(this.arquivosUsuarios, login)).mkdirs();
			
			return true;
		} else {
			return false;
		}
	}
	
	public DadosUsuario conferirLogin(String login, String senha) {
		if(this.usuarioExiste(login)) {
			DadosUsuario usuarioLoginFornecido = this.conjuntoUsers.get(login); 
			
			if(usuarioLoginFornecido.senhaEstaCerta(senha)) {
				return usuarioLoginFornecido;
			} else {
				return null;
			}
		} else {
			return null;
		}
	}
	
	public boolean usuarioExiste(String login) {
		return this.conjuntoUsers.containsKey(login);
	}
	
	public Arquivo gerarArvoreArquivos(String login) {
		File userFolder = new File(this.arquivosUsuarios, login);
		
		return new Arquivo(userFolder);
	}
	
	/*public File gerarArquivoUsuario(String login) {
		if(this.usuarioExiste(login)) {
			File userFolder = new File(this.arquivosUsuarios, login);
			File f = new File(this.folderTemp, login+".fl");
			
			try {
				if(!f.exists()) {
					f.createNewFile();
				}
				PrintStream stream = new PrintStream(f);
				
				this.criarArquivo(f, userFolder, stream);
				
				stream.close();
			} catch (FileNotFoundException e) {
			} catch (IOException e) {
			}
			
			return f;
		} else {
			return null;
		}
	}
	
	private void criarArquivo(File f, File folder, PrintStream stream) {
		long lm = folder.lastModified();
		
		if(folder.isDirectory()) {
			File[] conteudo = folder.listFiles();
			
			stream.printf("D %d %s %d\n", conteudo.length, folder.getName(), lm);
			
			for (int i = 0; i < conteudo.length; i++) {
				criarArquivo(f, conteudo[i], stream);
			}
			
		} else {
			stream.printf("A %s %d\n", folder.getName(), lm);
		}
	}*/
	
	@Override
	protected void finalize() throws Throwable {
		this.salvarConfig();
		super.finalize();
	}
}
